<?php
/**
 * Created by PhpStorm.
 * User: Lee
 * Date: 2020/1/3
 * Time: 9:51
 */
namespace App\Services\System;

use App\Common\Exception\ErrorException;
use App\Common\Utils\Helper;
use App\Models\System\Dicitem;
use App\Models\System\Scale;
use App\Models\System\ScaleDetail;
use App\Models\System\User;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use mysql_xdevapi\Exception;

/**
 * 系统管理-量表 (服务)
 */
class ScaleService
{
    /** @var \App\Repositories\System\ScaleRepository $scaleRepository */
    private $scaleRepository;

    public function __construct()
    {
        $this->scaleRepository = app('scaleRepository');
    }

    /**
     * @Description: 获取列表
     * @Author: kzj
     * @datetime: 2022-11-25
     */
    public function list($request)
    {
        $page = $request['page'] ?? 1;
        $limit = $request['limit'] ?? 10;
        $filters = [];

        // 搜索
        // if (isset($request['search']['type']) && !empty($request['search']['type'])){
        //     $filters[] = ['type', '=', $request['search']['type']];
        // }
        if (isset($request['search']['term_id']) && !empty($request['search']['term_id'])){
            $filters[] = ['term_id', '=', $request['search']['term_id']];
        }
        if (isset($request['search']['opt_name']) && !empty($request['search']['opt_name'])){
            $optName = Helper::check_param($request['search']['opt_name']);
            $filters[] = ['opt_name', 'like', '%'.$optName.'%'];
        }  
        if(isset($request['search']['sub_date']) && !empty($request['search']['sub_date'])){     
            $awardDate = explode(' - ',$request['filtesearchrs']['sub_date']);
            $filters[] = ['created_at','>=',$awardDate[0]];
            $filters[] = ['created_at','<=',$awardDate[1]];
        }
        if (isset($request['search']['keyword']) && !empty($request['search']['keyword'])){
            $keyword = Helper::check_param($request['search']['keyword']);
            $filters[] = [DB::raw("(opt_name like '%{$keyword}%')"),'1'];
        }
 
        $output = Scale::with('term')
            ->when(!empty($filters), function($q) use($filters) {
                $q->where($filters);
            })
            ->orderBy('id', 'desc')
            ->paginate($limit, '*', 'page', $page);
        
        $result = [
            'total' => $output->total(), 
            'data' => $output->items(),
            'per_page' => $output->perPage()
        ];

        return $result;
    }

    /**
     * @Description: 新增量表
     * @Author: kzj
     * @datetime: 2022-11-25
     */
    public function add($request)
    {
      
        $user = Auth::user();
        $request['user_id'] = $user->id;
        $request['opt_name'] = $user->nickname;
        
        unset($request['file']);
        unset($request['score']);
        $dicArr = Dicitem::where('diccode', 'LBCJ')->get();

        $request['tier'] = $dicArr->where('diccode', 'LBCJ')->where('itemcode', $request['tier_code'])->first()->itemname;

        if(!empty($request['files'])){
            $files = json_decode($request['files'],true);
            foreach($files as $k=>$v){
                if(empty($v)) unset($files[$k]);
            }
            $files = array_values($files);
            $request['files']  = json_encode($files);
        }else{
            unset($request['files']);
        }
        
        $result = Scale::create($request);

        return $result;
    }

    /**
     * @Description: 量表复制
     * @Author: kzj
     * @datetime: 2022-11-25
     */
    public function copy($request)
    {
        if (!$request['id'] || !$request['name']) {
            throw new \Exception('参数错误！');
        }

        $user = Auth::user();

        DB::beginTransaction();
        try
        {
            $scale= Scale::find($request['id'])->replicate();

            $scale->name = $request['name'];
            $scale->user_id = $user->id;
            $scale->opt_name = $user->nickname;
            $scale->save();

            $details = ScaleDetail::whereScaleId($request['id'])->wherePid(0)->with('child')->get();
            foreach($details as $d) {
                $this->copyDetails($d, $scale->id);
            }
            DB::commit();
        }
        catch(\Exception $e)
        {
            DB::rollBack();
            Log::error($e->getMessage());
            throw new \Exception('数据保存错误！');
        }

        return true;
    }

    /**
     * 考核量表内容复制
     */
    public function copyDetails($d, $scaleId, $topId = 0, $pid = 0, $thread = [])
    {
        $detail= ScaleDetail::find($d->id)->replicate();

        $detail->top_id = $topId;
        $detail->pid = $pid;
        $detail->scale_id = $scaleId;
        $detail->thread = collect($thread)->implode(',');
        $detail->sort = collect($thread)->sum();
        $detail->save();

        $topId = $topId > 0 ? $topId : $detail->id;
        $pid = $detail->id;
        $thread[] = $pid;

        if($d->child->count()) {
            foreach($d->child as $c) {
                $this->copyDetails($c, $scaleId, $topId, $pid, $thread);
            }
        }
    }

    /**
     * @Description: 获取单条数据
     * @Author: kzj
     * @datetime: 2022-11-24
     */
    public function getOne($request)
    {
        if (!$request['id']) {
            throw new \Exception('参数错误！');
        }

        $scale = Scale::whereId($request['id'])->with('detail', 'tableDetail')->first();

        $tableData = $this->scaleRepository->toTableData($scale->tableDetail);
        
        $result = [
            'scale' => $scale,
            'table_data' => $tableData
        ];

        return $result;
    }

    /**
     * @Description: 编辑量表
     * @Author: kzj
     * @datetime: 2022-11-25
     */
    public function edit($request)
    {
        if (!$request['id']) {
            throw new \Exception('参数错误！');
        } else {
            $scaleId = $request['id'];
        }

        unset($request['id']);
        unset($request['file']);
        unset($request['score']);
        $dicArr = Dicitem::where('diccode', 'LBCJ')->get();

        $request['tier'] = $dicArr->where('diccode', 'LBCJ')->where('itemcode', $request['tier_code'])->first()->itemname;

        if(!empty($request['files'])){
            $files = json_decode($request['files'],true);
            foreach($files as $k=>$v){
                if(empty($v)) unset($files[$k]);
            }
            $files = array_values($files);
            $request['files']  = json_encode($files);
        }else{
            unset($request['files']);
        }
        
        $result = Scale::whereId($scaleId)->update($request);

        return $result;
    }
    
    /**
     * @Description: 量表删除
     * @Author: kzj
     * @datetime: 2022-11-27
     */
    public function del($request)
    {
        if (!$request['id']) {
            throw new \Exception('参数错误！');
        }

        DB::beginTransaction();
        try
        {
            ScaleDetail::whereScaleId($request['id'])->delete();
            $result = Scale::whereId($request['id'])->delete();

            DB::commit();
        }
        catch(\Exception $e)
        {
            DB::rollBack();
            Log::error($e->getMessage());
            throw new \Exception('数据保存错误！');
        }

        return $result;
    }

    /**
     * @Description: 量表考核内容新增
     * @Author: kzj
     * @datetime: 2022-11-26
     */
    public function addDetail($request)
    {
     
        if (!$request['scale_id'] || empty($request['title'])) {
            throw new \Exception('参数错误！');
        }
        // if (!$request['score']) {
        //     throw new \Exception('满分数据必填且不为0');
        // }
       
        //$userInfo = User::where('user_id', $request['reviewer'])->first();
   
        $count = count($request['title']);
        $topId = 0;
        $pid = 0;
        $thread = [];
        DB::beginTransaction();
        try
        {
            foreach($request['title'] as $k => $t) {
                if($k > 1) {
                    $saveData = [
                        'pid' => $pid,
                        'top_id' => $topId,
                        'scale_id' => $request['scale_id'],
                        'title' => $t,
                        //'score' => $k == $count ? $request['score'] : null,
                        'min_score' => (isset($request['min_score']) && $k == $count) ? $request['min_score'] : 0,
                        'max_score' => (isset($request['max_score']) && $k == $count) ? $request['max_score'] : 0,
                        //'desc' => $k == $count ? $request['desc'] : '',
                        //'self_rate' => $k == $count ? $request['self_rate'] : 0,
                        //'reviewer' => $k == $count ? $request['reviewer'] : '',
                        //'review_name' => $k == $count ? $userInfo->user_name : '',
                        'level' => $k,
                        'tier' => $request['tier'],
                        'is_end' => $k == $count ? 1 : 0,
                        'thread' => collect($thread)->implode(','),
                        'sort' => collect($thread)->sum(),
                        'module' => !empty($request['module'])?$request['module']:'',
                        'scale_index' => !empty($request['scale_index'])?$request['scale_index']:'',

                        'single_score' => (isset($request['single_score']) && $k == $count) ?$request['single_score']:0,
                        'default_score' => (isset($request['default_score']) && $k == $count) ?$request['default_score']:0,
                        'check_module' => (isset($request['check_module']) && !empty($request['check_module'])) ?json_encode($request['check_module']):'',
                        'check_module_text' => isset($request['check_module_text'])?$request['check_module_text']:'',
                    ];
                   
                } else {
     
                    //一级
                    $saveData = [
                        'pid' => $pid,
                        'scale_id' => $request['scale_id'],
                        'title' => $t,
                        //'score' => $count == 1 ? $request['score'] : null,
                        'min_score' => (isset($request['min_score']) && $k == $count) ? $request['min_score'] : 0,
                        'max_score' => (isset($request['max_score']) && $k == $count) ? $request['max_score'] : 0,
                        //'desc' => $count == 1 ? $request['desc'] : '',
                        //'self_rate' => $count == 1 ? $request['self_rate'] : 0,
                        //'reviewer' => $count == 1 ? $request['reviewer'] : '',
                        //'review_name' => $count == 1 ? $userInfo->user_name : '',
                        'level' => 1,
                        'tier' => $request['tier'],
                        'is_end' => $count == 1 ? 1 : 0,
                        'thread' => collect($thread)->implode(','),
                        'sort' => collect($thread)->sum(),
                        'module' => !empty($request['module'])?$request['module']:'',
                        'scale_index' => !empty($request['scale_index'])?$request['scale_index']:'', 

                        'single_score' => (isset($request['single_score']) && $k == $count) ?$request['single_score']:0,
                        'default_score' => (isset($request['default_score']) && $k == $count) ?$request['default_score']:0,
                        'check_module' => (isset($request['check_module']) && !empty($request['check_module'])) ?json_encode($request['check_module']):'',
                        'check_module_text' => isset($request['check_module_text'])?$request['check_module_text']:'',
                    ];
                  
                }
               
                $detail = ScaleDetail::create($saveData);
                $pid = $detail->id;
                $thread[] = $pid;
                if($k <= 1) {
                    $topId = $detail->id;
                }
            }

            $details = ScaleDetail::whereScaleId($request['scale_id'])->get();
            Scale::whereId($request['scale_id'])->update(['score' => $details->sum('score')]);

            DB::commit();
        }
        catch(\Exception $e)
        {
            DB::rollBack();
            Log::error($e->getMessage());
            throw new \Exception('数据保存错误！');
        }

        return true;
        // return $result;
    }

    /**
     * @Description: 量表考核行内容新增
     * @Author: kzj
     * @datetime: 2022-11-26
     */
    public function addRowDetail($request)
    {
        if (!$request['scale_id'] || !$request['top_id']  || empty($request['title'])) {
            throw new \Exception('参数错误！');
        }
        // if (!$request['score']) {
        //     throw new \Exception('满分数据必填且不为0');
        // }
        
        //$userInfo = User::where('user_id', $request['reviewer'])->first();

        $count = count($request['title']);
        $topId = $request['top_id'];
        $pid = $request['top_id'];
        $thread = [$request['top_id']];
        DB::beginTransaction();
        try
        {
            foreach($request['title'] as $k => $t) {
                if($k > 1) {
                    $saveData = [
                        'pid' => $pid,
                        'top_id' => $topId,
                        'scale_id' => $request['scale_id'],
                        'title' => $t,
                        //'score' => $k == $count ? $request['score'] : null,
                        'min_score' => (isset($request['min_score']) && $k == $count) ? $request['min_score'] : 0,
                        'max_score' => (isset($request['max_score']) && $k == $count) ? $request['max_score'] : 0,
                        //'desc' => $k == $count ? $request['desc'] : '',
                        //'self_rate' => $k == $count ? $request['self_rate'] : 0,
                        //'reviewer' => $k == $count ? $request['reviewer'] : '',
                        //'review_name' => $k == $count ? $userInfo->user_name : '',
                        'level' => $k,
                        'tier' => $request['tier'],
                        'is_end' => $k == $count ? 1 : 0,
                        'thread' => collect($thread)->implode(','),
                        'sort' => collect($thread)->sum(),
                        'module' => !empty($request['module'])?$request['module']:'',
                        'scale_index' => !empty($request['scale_index'])?$request['scale_index']:'',

                        'single_score' => (isset($request['single_score']) && $k == $count) ?$request['single_score']:0,
                        'default_score' => (isset($request['default_score']) && $k == $count) ?$request['default_score']:0,
                        'check_module' => (isset($request['check_module']) && !empty($request['check_module'])) ?json_encode($request['check_module']):'',
                        'check_module_text' => isset($request['check_module_text'])?$request['check_module_text']:'',
                    ];

                    $detail = ScaleDetail::updateOrCreate(['pid' => $pid, 'top_id' => $topId, 'title' => $t, 'scale_id' => $request['scale_id']], $saveData);
                    $pid = $detail->id;
                    $thread[] = $pid;
                }
            }

            $details = ScaleDetail::whereScaleId($request['scale_id'])->get();
            Scale::whereId($request['scale_id'])->update(['score' => $details->sum('score')]);

            DB::commit();
        }
        catch(\Exception $e)
        {
            DB::rollBack();
            Log::error($e->getMessage());
            throw new \Exception('数据保存错误！');
        }

        return true;
    }

    /**
     * @Description: 量表考核内容编辑
     * @Author: kzj
     * @datetime: 2022-11-26
     */
    public function editDetail($request)
    {
        if (!$request['id'] || empty($request['title'])) {
            throw new \Exception('参数错误！');
        }
        // if (!$request['score']) {
        //     throw new \Exception('满分数据必填且不为0');
        // }
        // dd($request);
        $detailId = $request['id'];
        $titles = $request['title'];

       // $userInfo = User::where('user_id', $request['reviewer'])->first();
       // $request['review_name'] = $userInfo->user_name;

        unset($request['id']);
        unset($request['title']);
         $request['check_module'] = !empty($request['check_module'])?json_encode($request['check_module']):'';

        DB::beginTransaction();
        try
        {
            $detail = ScaleDetail::whereId($detailId)->with('parent')->first();

            $this->updateParentInfo($detail, $titles);
            
            $result = ScaleDetail::whereId($detailId)->update($request);

            //更新量表总分
            $details = ScaleDetail::whereScaleId($detail->scale_id)->get();
            Scale::whereId($detail->scale_id)->update(['score' => $details->sum('score')]);

            DB::commit();
        }
        catch(\Exception $e)
        {
            DB::rollBack();
            Log::error($e->getMessage());
            throw new \Exception('数据保存错误！');
        }

        return $result;
    }

    protected function updateParentInfo($d, $t)
    {
        $threadArr = $this->getThreadArr($d);
        $thread = collect($threadArr);
        $thread->pop();

        ScaleDetail::whereId($d->id)->update([
            'title' => $t[$d->level],
            'thread' => $thread->sort()->implode(','),
            'sort' => $thread->sum()
        ]);

        if($d->parent) {
            return $this->updateParentInfo($d->parent, $t);
        }
    }

    protected function getThreadArr($d, $result = [])
    {
        $result[] = $d->pid;

        if($d->parent) {
            return $this->getThreadArr($d->parent, $result);
        }

        return $result;
    }
    
    /**
     * @Description: 量表考核内容删除
     * @Author: kzj
     * @datetime: 2022-11-26
     */
    public function delDetail($request)
    {
        if (!$request['id']) {
            throw new \Exception('参数错误！');
        }

        DB::beginTransaction();
        try
        {
            $detail = ScaleDetail::whereId($request['id'])->with('scale')->first();

            $score = $detail->scale->score - $detail->score;
            Scale::whereId($detail->scale_id)->update(['score' => $score]);

            $result = ScaleDetail::whereId($request['id'])->delete();

            DB::commit();
        }
        catch(\Exception $e)
        {
            DB::rollBack();
            Log::error($e->getMessage());
            throw new \Exception('数据保存错误！');
        }

        return $result;
    }
    
    /**
     * @Description: 单个量表考核内容修改
     * @Author: kzj
     * @datetime: 2022-11-27
     */
    public function updateDetail($request)
    {
        if (!$request['id']) {
            throw new \Exception('参数错误！');
        }

        DB::beginTransaction();
        try
        {
            if (isset($request['reviewer']) && !empty($request['reviewer'])) {
                $userInfo = User::where('user_id', $request['reviewer'])->first();
                $request['review_name'] = $userInfo->user_name;
            }
            if (isset($request['score']) && !empty($request['score'])) {
                $detail = ScaleDetail::whereId($request['id'])->first();
    
                //查询不包括该条数据的所有量表内容
                $details = ScaleDetail::whereScaleId($detail->scale_id)->where('id', '!=', $request['id'])->get();
    
                $score = $details->sum('score') + $request['score'];
    
                Scale::whereId($detail->scale_id)->update(['score' => $score]);
            }

            $result = ScaleDetail::whereId($request['id'])->update($request);

            DB::commit();
        }
        catch(\Exception $e)
        {
            DB::rollBack();
            Log::error($e->getMessage());
            throw new \Exception('数据保存错误！');
        }
        

        return $result;
    }
    
    /**
     * @Description: 考核量表下拉选择数据
     * @Author: kzj
     * @datetime: 2022-11-27
     */
    public function selectList($request)
    {
        $type = isset($request['type']) && !empty($request['type']) ? $request['type'] : 0;

        $result = Scale::when($type, function($q) use($type) {
            $q->whereType($type);
        })->get();

        return $result;
    }
}
